package com.nari.ncps.screen.service.impl;


import com.nari.ncps.screen.common.constant.Mn;
import com.nari.ncps.screen.dto.excelbase.ExcelBasicInfo;
import com.nari.ncps.screen.common.enums.ModuleProductEnum;
import com.nari.ncps.screen.common.pojo.ApiResponse;
import com.nari.ncps.screen.service.excelhandler.ExcelParseService;
import com.nari.ncps.screen.service.ImportFileService;
import org.apache.commons.logging.Log;
import org.apache.commons.logging.LogFactory;
import org.apache.poi.ss.usermodel.*;
import org.apache.poi.xssf.usermodel.XSSFCell;
import org.apache.poi.xssf.usermodel.XSSFRow;
import org.apache.poi.xssf.usermodel.XSSFSheet;
import org.apache.poi.xssf.usermodel.XSSFWorkbook;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;

import java.io.*;
import java.text.SimpleDateFormat;
import java.util.ArrayList;
import java.util.List;
import java.util.Objects;
import java.util.regex.Matcher;
import java.util.regex.Pattern;

import static cn.afterturn.easypoi.util.PoiCellUtil.getCellValue;


@Service
public class ImportFileServiceImpl implements ImportFileService {


    private static final Log logger = LogFactory.getLog(ImportFileServiceImpl.class.getName());

    @Autowired
    private ExcelParseService excelParseService;


    @Override
    public ApiResponse<Object> standardUpload(MultipartFile file, Integer id)  throws Exception  {

        InputStream in = file.getInputStream();
        byte[] byteArray = toByteArray(in);

        File converFile = new File(Objects.requireNonNull(file.getOriginalFilename()));
        file.transferTo(converFile);
        String filePath = converFile.getAbsolutePath();
        String fileName = file.getOriginalFilename();

        try (InputStream inputStream = new ByteArrayInputStream(byteArray)) {
            XSSFWorkbook wb = new XSSFWorkbook(inputStream);

            //step1.获取基础信息，需要解析几张表，数据是哪里开始
            List<ExcelBasicInfo> analysisTables = importBasicInfo(wb, byteArray);

            logger.info("===" + ModuleProductEnum.getName(id) + "产业,共开启" +analysisTables.size()+ "个模块");
            //step2.解析入库
            if(!analysisTables.isEmpty()) {
                for(ExcelBasicInfo excelBasicInfo : analysisTables) {
                    logger.info("===>分别为,"+ excelBasicInfo.getTableName()+":"+excelBasicInfo.getTableEnName());
                    logger.info("===>需要处理行数为,数据开始行数："+ excelBasicInfo.getDataBegin()
                            +",数据结束行:"+excelBasicInfo.getDataEnd());

                    //核心开始解析入库
                    ApiResponse<Object> parseResponse = excelParseService.excelParseToDB(wb,excelBasicInfo,byteArray);

                }
            }
        }

        return ApiResponse.succeed("成功导入");
    }


    private String getCellValue (Cell cell){
        if (cell == null) return "null";
        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return new SimpleDateFormat("yyyy-MM-dd").format(cell.getDateCellValue());
                }
                return String.valueOf(cell.getNumericCellValue());
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "unknown";
        }
    }




    /**
     *  获取 导入表格的基本信息
     * @param wb wb
     * @param byteArray 流副本
     * @return 返回表格基本信息集合
     * @throws Exception 异常
     */
    private List<ExcelBasicInfo> importBasicInfo(XSSFWorkbook wb , byte[] byteArray) throws Exception {
        InputStream inputStream1 = new ByteArrayInputStream(byteArray);

        List<ExcelBasicInfo> result = new ArrayList<>();
        if (wb == null) {
            return result;
        }

        // 遍历所有工作表
        for (int sheetIndex = 0; sheetIndex < wb.getNumberOfSheets(); sheetIndex++) {
            XSSFSheet sheet = wb.getSheetAt(sheetIndex);
            if (sheet == null) continue;

            List<ExcelBasicInfo> sheetConfigs = parseSheetStructure(sheet);
            result.addAll(sheetConfigs);
        }
        return result;
    }


    /**
     *  第一次解析基础信息
     * @param sheet sheet
     * @return 基础信息集合
     */
    private List<ExcelBasicInfo> parseSheetStructure(XSSFSheet sheet) {
        List<ExcelBasicInfo> configs = new ArrayList<>();

        // 遍历每一行，查找业务子域的开始位置
        for (int rowNum = 0; rowNum <= sheet.getLastRowNum(); rowNum++) {
            XSSFRow row = sheet.getRow(rowNum);
            if (row == null) continue;

            // 查找"业务子域"标识
            XSSFCell firstCell = row.getCell(0);
            if (firstCell != null && firstCell.getCellType() == CellType.STRING) {
                String cellValue = firstCell.getStringCellValue().trim();
                if ("业务子域".equals(cellValue)) {
                    ExcelBasicInfo config = parseBusinessDomainBlock(sheet, rowNum);
                    if (config != null && "开启".equalsIgnoreCase(config.getSwitchFlag())) {
                        configs.add(config);
                    }
                }
            }
        }

        return configs;
    }


    /**
     *  解析每一个模块的 基本信息
     * @param sheet sheet页
     * @param startRow  开始行数
     * @return 模块信息域
     */
    private ExcelBasicInfo parseBusinessDomainBlock(XSSFSheet sheet, int startRow) {
        ExcelBasicInfo config = new ExcelBasicInfo();

        try {
            // 解析业务子域
            XSSFRow domainRow = sheet.getRow(startRow);
            String businessDomain = getCellStringValue(domainRow, 1);

            // 解析适用接口 (下一行)
            XSSFRow interfaceRow = sheet.getRow(startRow + 1);
            String interfaces = parseInterfaces(interfaceRow);

            // 解析表信息 (下两行)
            XSSFRow tableInfoRow = sheet.getRow(startRow + 2);
            String tableName = getCellStringValue(tableInfoRow, 1); // 中文表名
            String tableEnName = getCellStringValue(tableInfoRow, 2); // 英文表名

            // 解析描述 (下三行)
            XSSFRow descRow = sheet.getRow(startRow + 3);
//            String tableDesc = parseDescription(descRow);

            //------------------------  以下是数据表的区间   ------------------------

            // 解析开关状态 (下四行)
            XSSFRow switchRow = sheet.getRow(startRow + 4);
            String switchFlag = parseSwitchFlag(switchRow);

//            // 查找数据开始和结束行号
//            int[] dataRange = findDataRange(sheet, startRow + 5);

            // 根据开关状态决定是否查找数据范围
            if ("开启".equals(switchFlag)) {
                // 查找数据开始和结束行号
//                int[] dataRange = findDataRange(sheet, startRow + 5);
                int[] dataRange = findDataRange(sheet, startRow + 4);
                config.setDataBegin(dataRange[0]);
                config.setDataEnd(dataRange[1]);
            } else {
                // 关闭状态下，数据开始和结束行都设为0
                config.setDataBegin(0);
                config.setDataEnd(0);
            }

            // 设置配置对象
            config.setBusinessDomain(businessDomain);
            config.setInterfaces(interfaces);
//            config.setTableInfo(tableInfo);
//            config.setTableDesc(tableDesc);
            config.setTableName(tableName);
            config.setTableEnName(tableEnName);
            config.setSwitchFlag(switchFlag);

            //---------  以下是数据表的区间   ------------
            config.setTableDataStartRow(startRow+4);

        } catch (Exception e) {
            System.err.println("解析业务子域块时出错，起始行: " + startRow + ", 错误: " + e.getMessage());
            return null;
        }

        return config;
    }


    private String parseInterfaces(XSSFRow interfaceRow) {
        if (interfaceRow == null) return "";

        List<String> interfaceList = new ArrayList<>();
        // 从第1列开始遍历适用接口（跳过"适用接口"标题）
        for (int i = 1; i < interfaceRow.getLastCellNum(); i++) {
            String interfaceValue = getCellStringValue(interfaceRow, i);
            if (interfaceValue != null && !interfaceValue.trim().isEmpty()) {
                interfaceList.add(interfaceValue.trim());
            }
        }

        return String.join(",", interfaceList);
    }

    private String parseDescription(XSSFRow descRow) {
        if (descRow == null) return "";

        StringBuilder descBuilder = new StringBuilder();
        // 从第1列开始遍历描述信息
        for (int i = 1; i < Math.min(descRow.getLastCellNum(), 10); i++) { // 限制列数避免过长
            String descValue = getCellStringValue(descRow, i);
            if (descValue != null && !descValue.trim().isEmpty()) {
                if (descBuilder.length() > 0) {
                    descBuilder.append(" ");
                }
                descBuilder.append(descValue.trim());
            }
        }

        return descBuilder.toString();
    }

    private String parseSwitchFlag(XSSFRow switchRow) {
        if (switchRow == null) return "关闭";

        String switchValue = getCellStringValue(switchRow, 0);
        if (switchValue != null) {
            switchValue = switchValue.trim();
            if ("开启".equals(switchValue) || "打开".equals(switchValue) || "启用".equals(switchValue)) {
                return "开启";
            }
        }
        return "关闭";
    }

//    private int[] findDataRange(XSSFSheet sheet, int startFromRow) {
//        int dataBegin = -1;
//        int dataEnd = -1;
//
//        // 查找数据开始行（第一个包含有效数据的行）
//        for (int i = startFromRow; i <= sheet.getLastRowNum(); i++) {
//            XSSFRow row = sheet.getRow(i);
//            if (row != null && isDataRow(row)) {
//                dataBegin = i;
//                break;
//            }
//        }
//
//        if (dataBegin == -1) {
//            return new int[]{-1, -1};
//        }
//
//        // 查找数据结束行
//        for (int i = dataBegin; i <= sheet.getLastRowNum(); i++) {
//            XSSFRow row = sheet.getRow(i);
//            if (row == null || !isDataRow(row) || isNewBusinessDomain(row)) {
//                dataEnd = i - 1;
//                break;
//            }
//            // 如果到最后一行都是数据
//            if (i == sheet.getLastRowNum()) {
//                dataEnd = i;
//            }
//        }
//
//        // 如果结束行小于开始行，调整
//        if (dataEnd < dataBegin) {
//            dataEnd = dataBegin;
//        }
//
//        return new int[]{dataBegin, dataEnd};
//    }

    public int[] findDataRange(Sheet sheet, int startRow) {
        int dataStartRow = -1;
        int dataEndRow = -1;

        // 查找数据开始行（跳过表头行）

        dataStartRow = startRow + 1;

//        for (int i = startRow; i <= sheet.getLastRowNum(); i++) {
//            Row row = sheet.getRow(i);
//            if (row != null && !isEmptyRow(row)) {
//
////                // 检查是否是数据行（包含数字数据）
////                if (isDataRow(row)) {
////                    dataStartRow = i;
////                    break;
////                }
//
//            }
//        }

//        if (dataStartRow == -1) {
//            return new int[]{-1, -1}; // 没有找到数据
//        }

        // 查找数据结束行
        dataEndRow = dataStartRow;
        for (int i = dataStartRow + 1; i <= sheet.getLastRowNum()+1; i++) {
            Row row = sheet.getRow(i);

            if (row == null || isEmptyRow(row)) {
                // 遇到空行，结束数据区域
                dataEndRow = i;
                break;
            } else if(isNewTableStart(row)) {
                // 遇到新表的开始标记
                dataEndRow = i - 1;
                break;
            }

//            if (row == null || isEmptyRow(row)) {
//                // 遇到空行，结束数据区域
//                dataEndRow = i - 1;
//                break;
//            } else if (isNewTableStart(row)) {
//                // 遇到新表的开始标记
////                dataEndRow = i - 1;
//                dataEndRow = i - 2;
//                break;
//            }
////            else if (isDataRow(row)) {
////                dataEndRow = i;
////            }
        }

        return new int[]{dataStartRow, dataEndRow};
    }

    // 判断是否为空行
    private boolean isEmptyRow(Row row) {
        if (row == null) return true;
        for (int i = 0; i < row.getLastCellNum(); i++) {
            Cell cell = row.getCell(i);
            if (cell != null && cell.getCellType() != CellType.BLANK) {
                String cellValue = getCellStringValue(cell);
                if (cellValue != null && !cellValue.trim().isEmpty()) {
                    return false;
                }
            }
        }
        return true;
    }

//    // 判断是否是数据行
//    private boolean isDataRow(Row row) {
//        if (row == null) return false;
//
//        // 检查第一列是否是年份数据（如2025）
//        Cell firstCell = row.getCell(0);
//        if (firstCell != null) {
//            String value = getCellStringValue(firstCell);
//            // 判断是否是年份格式的数字
//            if (value != null && value.matches("\\d{4}")) {
//                return true;
//            }
//        }
//        return false;
//    }

    // 判断是否是新表的开始
    private boolean isNewTableStart(Row row) {
        if (row == null) return false;

        Cell firstCell = row.getCell(0);
        if (firstCell != null) {
            String value = getCellStringValue(firstCell);
            // 检查是否是表开始标记
//            if ("业务子域".equals(value) || "开启".equals(value) || "关闭".equals(value)) {
            if ("业务子域".equals(value) ) {
                return true;
            }
        }
        return false;
    }

    // 获取单元格字符串值
    private String getCellStringValue(Cell cell) {
        if (cell == null) return null;

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue().trim();
            case NUMERIC:
                if (DateUtil.isCellDateFormatted(cell)) {
                    return cell.getDateCellValue().toString();
                } else {
                    return String.valueOf((int) cell.getNumericCellValue());
                }
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                return cell.getCellFormula();
            default:
                return "";
        }
    }



//
//    private int[] findDataRange(XSSFSheet sheet, int startFromRow) {
//        int dataBegin = -1;
//        int dataEnd = -1;
//
//        // 查找数据开始行（第一个包含有效数据的行）
//        for (int i = startFromRow; i <= sheet.getLastRowNum(); i++) {
//            XSSFRow row = sheet.getRow(i);
//            if (row != null && isDataRow(row)) {
//                dataBegin = i;
//                break;
//            }
//        }
//
//        if (dataBegin == -1) {
//            return new int[]{0, 0}; // 没有找到数据，返回0,0
//        }
//
//        // 查找数据结束行
//        for (int i = dataBegin; i <= sheet.getLastRowNum(); i++) {
//            XSSFRow row = sheet.getRow(i);
//            if (row == null || !isDataRow(row) || isNewBusinessDomain(row)) {
//                dataEnd = i - 1;
//                break;
//            }
//            // 如果到最后一行都是数据
//            if (i == sheet.getLastRowNum()) {
//                dataEnd = i;
//            }
//        }
//
//        // 如果结束行小于开始行，调整
//        if (dataEnd < dataBegin) {
//            dataEnd = dataBegin;
//        }
//
//        return new int[]{dataBegin, dataEnd};
//    }

    private boolean isDataRow(XSSFRow row) {
        if (row == null) return false;

        // 检查是否是数据行（包含年份、月份等数值数据）
        int dataCellCount = 0;
        for (int i = 0; i < row.getLastCellNum(); i++) {
            XSSFCell cell = row.getCell(i);
            if (cell != null) {
                if (cell.getCellType() == CellType.NUMERIC) {
                    dataCellCount++;
                } else if (cell.getCellType() == CellType.STRING) {
                    String cellValue = cell.getStringCellValue().trim();
                    // 检查是否是年份月份格式或数字
                    if (isYearMonthFormat(cellValue) || isNumeric(cellValue) ||
                            isChineseText(cellValue)) {
                        dataCellCount++;
                    }
                }
            }
        }

        // 如果有一定数量的数据单元格，认为是数据行
        return dataCellCount >= 3; // 至少3个数据单元格
    }

    private boolean isNewBusinessDomain(XSSFRow row) {
        if (row == null) return false;

        XSSFCell firstCell = row.getCell(0);
        if (firstCell != null && firstCell.getCellType() == CellType.STRING) {
            String cellValue = firstCell.getStringCellValue().trim();
            return "业务子域".equals(cellValue);
        }
        return false;
    }

    private boolean isYearMonthFormat(String value) {
        if (value == null) return false;
        Pattern pattern = Pattern.compile("\\d{4}-\\d{1,2}");
        Matcher matcher = pattern.matcher(value.trim());
        return matcher.matches();
    }

    private boolean isNumeric(String str) {
        if (str == null || str.trim().isEmpty()) return false;
        try {
            Double.parseDouble(str.trim());
            return true;
        } catch (NumberFormatException e) {
            return false;
        }
    }

    private boolean isChineseText(String str) {
        if (str == null || str.trim().isEmpty()) return false;
        // 简单的中文文本检测（包含中文字符）
        Pattern pattern = Pattern.compile("[\\u4e00-\\u9fa5]");
        Matcher matcher = pattern.matcher(str);
        return matcher.find();
    }

    private String getCellStringValue(XSSFRow row, int cellIndex) {
        if (row == null) return null;
        XSSFCell cell = row.getCell(cellIndex);
        if (cell == null) return null;

        switch (cell.getCellType()) {
            case STRING:
                return cell.getStringCellValue();
            case NUMERIC:
                return String.valueOf((int) cell.getNumericCellValue());
            case BOOLEAN:
                return String.valueOf(cell.getBooleanCellValue());
            case FORMULA:
                try {
                    return cell.getStringCellValue();
                } catch (Exception e) {
                    try {
                        return String.valueOf(cell.getNumericCellValue());
                    } catch (Exception e2) {
                        return String.valueOf(cell.getBooleanCellValue());
                    }
                }
            default:
                return null;
        }
    }


    /**
     * 将流转换成字节数组
     */
    public byte[] toByteArray(InputStream inputStream) throws IOException {
        ByteArrayOutputStream outputStream = new ByteArrayOutputStream();
        byte[] buffer = new byte[Mn.M_1024_N];
        int length;
        while ((length = inputStream.read(buffer)) != -1) {
            outputStream.write(buffer, 0, length);
        }

        byte[] data = outputStream.toByteArray();
        outputStream.close();
        inputStream.close();
        return data;
    }

}
